/*
 * @Author: kanglang
 * @Date: 2020-12-09 14:25:51
 * @LastEditors: 汪滔
 * @LastEditTime: 2021-06-03 11:44:00
 * @Description: 用户反馈--语音部分
 */
import React, { Component } from 'react';
import { StyleSheet, View, Platform, NativeModules } from 'react-native';
import { msg } from '@/common';
import Sound from '@/common/sound';
import { AudioRecorder, AudioUtils } from '@/common/record';
import { isAndroid } from '@/styles';
import PlayVoiceItem from './play-voice-item';
import PressTalk from './press-talk';

export default class VoiceBox extends Component {
    prepareRecordingPath = (path) => {
      const option = {
        SampleRate: 22050, // 采样率
        Channels: 1, // 通道
        AudioQuality: 'Low', // 音质 Low Medium High
        AudioEncoding: isAndroid ? 'aac' : 'wav', // 音频编码 wavz
        OutputFormat: 'mpeg_4', // 输出格式
        MeteringEnabled: false, // 是否计量
        MeasurementMode: false, // 测量模式
        AudioEncodingBitRate: 32000, // 音频编码比特率
        IncludeBase64: true, // 是否是base64格式
        AudioSource: 0, // 音频源
      };
      AudioRecorder.prepareRecordingAtPath(path, option);
    }

    constructor(props) {
      super(props);
      this.state = {
        speaking: false,
        audioPath: `${AudioUtils.DocumentDirectoryPath}/user_feedback_${new Date().getTime()}.wav`,
        hasPermission: '',
        voiceTime: 0,
        isPlayArr: [false, false, false],
        isCalled: false
      };
    }

    componentDidMount() {
      const { hasPermission } = this.state;
      if (!hasPermission) {
        this.getAudioAuthorize();
      }
    }

    // 按下开始说话
    startSpeaking = async () => {
      const { audioPath } = this.state;
      if (this.whoosh) {
        this.whoosh.stop();
        this.whoosh.release();
      }
      this.setState({ speaking: true, isPlayArr: [false, false, false] });
      try {
        this.prepareRecordingPath(audioPath);
      } catch (error) {
        console.log(error);
      }

      // 先判断有没有权限
      if (!this.state.hasPermission) {
        this.getAudioAuthorize();
        return;
      }
      try {
        await AudioRecorder.startRecording();
      } catch (err) {
        console.error(err);
      }
    }

    // 请求录音授权
    getAudioAuthorize = () => {
      const { audioPath } = this.state;
      AudioRecorder.requestAuthorization()
        .then(isAuthor => {
          if (!isAuthor || isAuthor == null) {
            if (Platform.OS != 'android') {
              NativeModules.WindowModule.showWindow(
                { title: '系统提示', content: '缺少权限，是否去手动开启权限？', leftStr: '退出', rightStr: '去设置' },
                (e) => {
                  if (e == 1) {
                    NativeModules.BridgeManager.openSettings();
                  }
                },
              );
            }
            return;
          }
          this.setState({ hasPermission: isAuthor });
          this.prepareRecordingPath(audioPath);
          // 录音进展
          AudioRecorder.onProgress = (data) => {
            this.setState({ voiceTime: Math.ceil(data.currentTime) });
            if (data.currentTime > 59) {
              this.stopSpeaking();
            }
          };
          // 完成录音
          AudioRecorder.onFinished = (data) => { };
        });
    }

    // 放起手势 保存录制的语音、时长
    stopSpeaking = async () => {
      if (this.whoosh) {
        this.whoosh.stop();
        this.whoosh.release();
      }
      const { speaking, audioPath, voiceTime } = this.state;
      if (voiceTime <= 1) {
        msg.emit('app:tip', { text: '说话时间太短了' });
        try {
          await AudioRecorder.stopRecording();
        } catch (error) {
          console.log(error);
        }
        this.setState({
          voiceTime: 0,
          speaking: false,
          audioPath: `${AudioUtils.DocumentDirectoryPath}/quick_audio_${new Date().getTime()}.wav`,
        }, () => {
          // 初始化录音
          try {
            this.prepareRecordingPath(audioPath);
          } catch (error) {
            console.log('初始化异常', error);
          }
        });
        return;
      }
      const { addVoice } = this.props;
      this.setState({ speaking: false, voiceTime: 0, });

      if (!speaking) {
        console.log('当前没有录音');
        return;
      }

      try {
        await AudioRecorder.stopRecording();
      } catch (error) {
        console.error(error);
      }
      this.setState({ audioPath: `${AudioUtils.DocumentDirectoryPath}/user_feedback_${new Date().getTime()}.wav` });
      addVoice && addVoice(audioPath, voiceTime);
    }

    // 删除当前语音
    delCurVoice = (index) => {
      if (this.whoosh) {
        this.whoosh.stop();
        this.whoosh.release();
      }
      const { delVoice } = this.props;
      delVoice && delVoice(index);
    }

    // 播放当前语音
    playVoice = (localVoice, index) => {
      this.setState({
        isPlayArr: [index === 0, index === 1, index === 2],
      });
      if (this.whoosh) {
        this.whoosh.pause();
      }
      let that = this;
      that.whoosh = new Sound(true, localVoice, '', (err) => {
        if (err) {
          msg.emit('app:tip', { text: '加载音频失败' });
          return;
        }
        that.whoosh.play(success => {
          this.setState({ isPlayArr: [false, false, false] });
          if (success) {
            that.whoosh.release();
            console.log('success - 播放成功');
          } else {
            console.log('播放失败');
          }
        });
      });
    }

    componentWillUnmount() {
      if (this.whoosh) {
        this.whoosh.stop();
        this.whoosh.release();
      }
    }

    render() {
      const { speaking, voiceTime, isPlayArr } = this.state;
      const { voiceList } = this.props;
      return (
        <View style={styles.container}>

          {/* 语音播放气泡条 */}
          {
            voiceList.length > 0 &&
                    voiceList.map((item, index) => {
                      return (
                        <PlayVoiceItem
                          key={index}
                          index={index}
                          source={voiceList}
                          isPlay={isPlayArr[index]}
                          voiceLen={item.voiceLen}
                          playVoice={() => this.playVoice(item.localVoice, index)}
                          delVoice={() => this.delCurVoice(index)}
                        />
                      );
                    })
          }
          {/* 按住说话 */}
          {
            voiceList.length < 3 &&
            <PressTalk
              speaking={speaking}
              voiceTime={voiceTime}
              startSpeaking={this.startSpeaking}
              stopSpeaking={this.stopSpeaking}
            />
          }
        </View>
      );
    }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#FFFFFF',
  },
});
